﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.ComponentModel;
using System.Drawing;
using System.Collections.ObjectModel;
using System.Collections;

namespace NetPE
{
    public class PrimitiveCollectionEditor<T> : BaseEditor
    {
        private DataGridViewTextBoxColumn val;
        private DataGridView view;

        public PrimitiveCollectionEditor()
        {
            view = new DataGridView();
            val = new DataGridViewTextBoxColumn();
            ((ISupportInitialize)view).BeginInit();
            this.SuspendLayout();

            view.BackgroundColor = Color.Black;
            view.BorderStyle = BorderStyle.None;
            view.ColumnHeadersVisible = false;
            view.Columns.Add(val);
            view.Dock = DockStyle.Fill;
            view.ForeColor = Color.Black;
            view.RowHeadersBorderStyle = DataGridViewHeaderBorderStyle.None;
            view.RowPostPaint += new DataGridViewRowPostPaintEventHandler(viewRowPostPaint);
            view.VirtualMode = true;
            view.CellValueNeeded += new DataGridViewCellValueEventHandler(viewCellValueNeeded);
            view.CellValuePushed += new DataGridViewCellValueEventHandler(viewCellValuePushed);
            view.CellParsing += new DataGridViewCellParsingEventHandler(viewCellParsing);
            view.NewRowNeeded += new DataGridViewRowEventHandler(viewNewRowNeeded);
            view.UserDeletingRow += new DataGridViewRowCancelEventHandler(viewUserDeletingRow);

            val.HeaderText = "Value";
            val.Name = "val";
            val.Width = 250;

            this.Controls.Add(view);
            ((ISupportInitialize)view).EndInit();
            this.ResumeLayout(false);

        }

        void viewUserDeletingRow(object sender, DataGridViewRowCancelEventArgs e)
        {
            (Object as IList).RemoveAt(e.Row.Index);
        }

        void viewNewRowNeeded(object sender, DataGridViewRowEventArgs e)
        {
            (Object as IList).Add(Convert.ChangeType(0, Object.GetType().GetInterface("IList`1").GetGenericArguments()[0]));
        }

        void viewCellParsing(object sender, DataGridViewCellParsingEventArgs e)
        {
            if (Object.GetType().GetInterface("IList`1").GetGenericArguments()[0].FullName.StartsWith("System.UInt"))
            {
                try
                {
                    ulong hex = Convert.ToUInt64(e.Value.ToString(), 16);
                    e.Value = Convert.ChangeType(hex, Object.GetType().GetInterface("IList`1").GetGenericArguments()[0]);
                }
                catch
                {
                    e.Value = (Object as IList)[e.RowIndex];
                }
                e.ParsingApplied = true;
            }
        }

        void viewRowPostPaint(object sender, DataGridViewRowPostPaintEventArgs e)
        {
            e.Graphics.DrawString(e.RowIndex.ToString("x3"), this.Font, Brushes.Black, e.RowBounds.Location.X + 15, e.RowBounds.Location.Y + ((e.RowBounds.Height - e.Graphics.MeasureString(e.RowIndex.ToString("x3"), this.Font).Height) / 2));
        }

        protected override void RefreshData()
        {
            view.RowCount = (Object as IList).Count + 1;
            if (Object.GetType().GetInterface("IList`1").GetGenericArguments()[0].FullName.StartsWith("System.UInt"))
                val.DefaultCellStyle.Format = "x";
            else
                val.DefaultCellStyle.Format = "";
        }

        private void viewCellValueNeeded(object sender, DataGridViewCellValueEventArgs e)
        {
            if (e.RowIndex < (Object as IList).Count && e.ColumnIndex == 0)
            {
                e.Value = (Object as IList)[e.RowIndex];
            }
        }

        private void viewCellValuePushed(object sender, DataGridViewCellValueEventArgs e)
        {
            if (e.RowIndex < (Object as IList).Count && e.ColumnIndex == 0)
            {
                (Object as IList)[e.RowIndex] = e.Value;
            }
        }
    }
}
